package com.gopay.checkorder.service.task;

import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import org.apache.commons.lang3.time.StopWatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gopay.checkorder.dao.BisBankOrderQueryDAO;
import com.gopay.checkorder.service.BankOrderService;
import com.gopay.checkorder.service.alarm.OrderAlarmDataCollector;
import com.gopay.checkorder.service.alarm.OrderAlarmRecordStorage;
import com.gopay.checkorder.service.task.thread.CheckOrderThread;
import com.gopay.common.constants.bank.BankOrderStatus;
import com.gopay.common.domain.bank.BankOrder;
import com.gopay.common.util.ExecutorUtil;
import com.gopay.common.util.spring.SpringContextUtil;

public class IcbcCheckOrderTaskImpl implements Task {

	private final static Logger logger = LoggerFactory.getLogger("CHECK_ORDER");


	@Resource(name = "bisBankOrderQueryDAO")
	private BisBankOrderQueryDAO bisBankOrderQueryDAO;
	
    private static final int MAX_THREAD_COUNT=10;
    
    private ExecutorService threadPool = Executors.newFixedThreadPool(MAX_THREAD_COUNT);

	@Resource(name = "bankOrderService")
	private BankOrderService bankOrderService;

	@Resource(name = "orderAlarmRecordStorage")
	private OrderAlarmRecordStorage orderAlarmRecordStorage;
	
	private String BANK = "ICBC";

	/**
	 * 银行流水状态
	 */
	private String orderStatus;

	private void printLog(StopWatch sw, String bank, String orderStatus,
			String prefix) {
		sw.split();
		logger.error(prefix + "------,bank=" + BANK + ",orderStatus="
				+ orderStatus + ",耗时=" + sw.getSplitTime());
	}

	/**
	 * 任务执行
	 */
	public void doTask() {
        try{
        	StopWatch sw=new StopWatch();
            sw.start();
            printLog(sw,BANK,orderStatus,"IcbcCheckOrderTaskImpl------start");
            
            
            int pageSize = 300;
            int pageIndex = 1;
            int count = 0;
    
            checkBefore();
	        List<BankOrder> list = getCheckOrder(orderStatus, pageIndex, pageSize);
	         printLog(sw,BANK,orderStatus,"IcbcCheckOrderTaskImpl------list.size()="+list.size()+",pageIndex="+pageIndex);
	
	            // 订单对账报警采集者
				OrderAlarmDataCollector alarmCollector = new OrderAlarmDataCollector();
	            //订单队列	            
	            ConcurrentLinkedQueue<BankOrder> queue=new ConcurrentLinkedQueue<BankOrder>();
	            queue.addAll(list);
	
	            //同步锁存器
	            CountDownLatch latch = new CountDownLatch(queue.size());
	            
	          //线程池中线程全部参与
	            for(int i=0;i<MAX_THREAD_COUNT;i++){
	                CheckOrderThread thread=new CheckOrderThread(bankOrderService,queue,latch,alarmCollector);
	                threadPool.execute(thread);
	                 
	            }
	            // 同步锁存器等待所有线程执行完成
                if(!latch.await(118, TimeUnit.SECONDS)){
                    logger.error("同步锁存器等待超时了 latch.count=" + latch.getCount());
                    threadPool.awaitTermination(1, TimeUnit.SECONDS);
                }
                // 判断报警阈值并保存报警记录
       		  orderAlarmRecordStorage.store(alarmCollector);
	          
                printLog(sw,BANK,orderStatus,"IcbcCheckOrderTaskImpl------end");
                sw.stop();  
            
            
            
        
        }catch (Throwable t) {
            logger.error("执行对单Task时出现异常" ,t);
        } 
    }

	/**
     * 
     */
	private void checkBefore() {
	}

	/**
	 * 待对账订单笔数
	 * 
	 * @param orderStatus
	 * @param totalCheckTimes
	 * @return
	 */
	/*protected int getCheckOrderCount(String orderStatus) {
		int resCount = bisBankOrderQueryDAO.getCheckOrderCountByBank(
				orderStatus, BANK);
		if (resCount > MAX_SIZE) {
			resCount = MAX_SIZE;
		}
		return resCount;
	}*/

	/**
	 * 分页查询对账记录
	 * 
	 * @param orderStatus
	 * @param totalCheckTimes
	 * @param pageIndex
	 * @param pageSize
	 * @return
	 */
	protected List<BankOrder> getCheckOrder(String orderStatus, int pageIndex,
			int pageSize) {

		return bisBankOrderQueryDAO.getCheckOrderByBank(orderStatus, pageIndex,
				pageSize, BANK);
	}

	public void setOrderStatus(String orderStatus) {
		this.orderStatus = orderStatus;
	}

}
